/* ntdll.h.  Contains ntdll specific stuff not defined elsewhere.

   This file is part of Cygwin.

   This software is a copyrighted work licensed under the terms of the
   Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
   details. */

#pragma once

#include <w32api/ntstatus.h>

/* Values for Cygwin AF_UNIX socket reparse points. */
#define IO_REPARSE_TAG_CYGUNIX	(0x00006375)
extern GUID __cygwin_socket_guid;
#define CYGWIN_SOCKET_GUID (&__cygwin_socket_guid)

/* Custom Cygwin-only status codes. */
#define STATUS_THREAD_SIGNALED	((NTSTATUS)0xe0000001)
#define STATUS_THREAD_CANCELED	((NTSTATUS)0xe0000002)
#define STATUS_ILLEGAL_DLL_PSEUDO_RELOCATION ((NTSTATUS) 0xe0000269)

/* Simplify checking for a transactional error code. */
#define NT_TRANSACTIONAL_ERROR(s)	\
		(((ULONG)(s) >= (ULONG)STATUS_TRANSACTIONAL_CONFLICT) \
		 && ((ULONG)(s) <= (ULONG)STATUS_TRANSACTION_NOT_ENLISTED))

#define NtCurrentProcess() ((HANDLE) (LONG_PTR) -1)
#define NtCurrentThread()  ((HANDLE) (LONG_PTR) -2)

/* Creation information returned in IO_STATUS_BLOCK. */
#define FILE_SUPERSEDED     0
#define FILE_OPENED         1
#define FILE_CREATED        2
#define FILE_OVERWRITTEN    3
#define FILE_EXISTS         4
#define FILE_DOES_NOT_EXIST 5

/* Relative file position values in NtWriteFile call. */
#define FILE_WRITE_TO_END_OF_FILE      (-1LL)
#define FILE_USE_FILE_POINTER_POSITION (-2LL)

/* Device Characteristics. */
#define FILE_REMOVABLE_MEDIA           0x00000001
#define FILE_READ_ONLY_DEVICE          0x00000002
#define FILE_FLOPPY_DISKETTE           0x00000004
#define FILE_WRITE_ONCE_MEDIA          0x00000008
#define FILE_REMOTE_DEVICE             0x00000010
#define FILE_DEVICE_IS_MOUNTED         0x00000020
#define FILE_VIRTUAL_VOLUME            0x00000040
#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
#define FILE_DEVICE_SECURE_OPEN        0x00000100

/* Allocation type values in NtMapViewOfSection call. */
#define AT_EXTENDABLE_FILE 0x00002000
#define AT_ROUND_TO_PAGE 0x40000000

/* Lock type in NtLockVirtualMemory/NtUnlockVirtualMemory call. */
#define MAP_PROCESS 1
#define MAP_SYSTEM  2

/* Directory access rights (only in NT namespace). */
#define DIRECTORY_QUERY 1
#define DIRECTORY_TRAVERSE 2
#define DIRECTORY_CREATE_OBJECT 4
#define DIRECTORY_CREATE_SUBDIRECTORY 8
#define DIRECTORY_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED|0x0f)

/* Symbolic link access rights (only in NT namespace). */
#define SYMBOLIC_LINK_QUERY 1
#define SYMBOLIC_LINK_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x1)

/* Transaction access rights. */
#ifndef TRANSACTION_ALL_ACCESS
#define TRANSACTION_ALL_ACCESS (STANDARD_RIGHTS_REQUIRED | 0x3F)
#endif

/* Event object access rights. */
#define EVENT_QUERY_STATE 1

/* Semaphore access rights. */
#define SEMAPHORE_QUERY_STATE 1

/* Specific ACCESS_MASKSs for objects created in Cygwin. */
#define CYG_SHARED_DIR_ACCESS	(DIRECTORY_QUERY \
				 | DIRECTORY_TRAVERSE \
				 | DIRECTORY_CREATE_SUBDIRECTORY \
				 | DIRECTORY_CREATE_OBJECT \
				 | READ_CONTROL)
#define CYG_MUTANT_ACCESS	(MUTANT_QUERY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)
#define CYG_EVENT_ACCESS	(EVENT_QUERY_STATE \
				 | EVENT_MODIFY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)
#define CYG_SEMAPHORE_ACCESS	(SEMAPHORE_QUERY_STATE \
				 | SEMAPHORE_MODIFY_STATE \
				 | SYNCHRONIZE \
				 | READ_CONTROL)

/* Definitions for first parameter of RtlQueryRegistryValues. */
#define RTL_REGISTRY_ABSOLUTE 0
#define RTL_REGISTRY_SERVICES 1
#define RTL_REGISTRY_CONTROL 2
#define RTL_REGISTRY_WINDOWS_NT 3
#define RTL_REGISTRY_DEVICEMAP 4
#define RTL_REGISTRY_USER 5
#define RTL_REGISTRY_HANDLE 0x40000000
#define RTL_REGISTRY_OPTIONAL 0x80000000

/* Flags values for QueryTable parameter of RtlQueryRegistryValues. */
#define RTL_QUERY_REGISTRY_SUBKEY 0x01
#define RTL_QUERY_REGISTRY_TOPKEY 0x02
#define RTL_QUERY_REGISTRY_REQUIRED 0x04
#define RTL_QUERY_REGISTRY_NOVALUE 0x08
#define RTL_QUERY_REGISTRY_NOEXPAND 0x10
#define RTL_QUERY_REGISTRY_DIRECT 0x20
#define RTL_QUERY_REGISTRY_DELETE 0x40
#define RTL_QUERY_REGISTRY_NOSTRING 0x80

/* What RtlQueryProcessDebugInformation shall return. */
#define PDI_MODULES 0x01
#define PDI_HEAPS 0x04
#define PDI_HEAP_BLOCKS 0x10
#define PDI_WOW64_MODULES 0x40

/* VM working set list protection values.  Returned by NtQueryVirtualMemory. */
#define WSLE_PAGE_READONLY 0x001
#define WSLE_PAGE_EXECUTE 0x002
#define WSLE_PAGE_EXECUTE_READ 0x003
#define WSLE_PAGE_READWRITE 0x004
#define WSLE_PAGE_WRITECOPY 0x005
#define WSLE_PAGE_EXECUTE_READWRITE 0x006
#define WSLE_PAGE_EXECUTE_WRITECOPY 0x007
#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
#define WSLE_PAGE_SHAREABLE 0x100

/* Known debug heap flags */
#define HEAP_FLAG_NOSERIALIZE	       0x1
#define HEAP_FLAG_GROWABLE	       0x2
#define HEAP_FLAG_EXCEPTIONS	       0x4
#define HEAP_FLAG_NONDEFAULT	    0x1000
#define HEAP_FLAG_SHAREABLE	    0x8000
#define HEAP_FLAG_EXECUTABLE	   0x40000
#define HEAP_FLAG_DEBUGGED	0x40000000

#define FILE_VC_QUOTA_NONE              0x00000000
#define FILE_VC_QUOTA_TRACK             0x00000001
#define FILE_VC_QUOTA_ENFORCE           0x00000002
#define FILE_VC_QUOTA_MASK              0x00000003
#define FILE_VC_CONTENT_INDEX_DISABLED  0x00000008
#define FILE_VC_LOG_QUOTA_THRESHOLD     0x00000010
#define FILE_VC_LOG_QUOTA_LIMIT         0x00000020
#define FILE_VC_LOG_VOLUME_THRESHOLD    0x00000040
#define FILE_VC_LOG_VOLUME_LIMIT        0x00000080
#define FILE_VC_QUOTAS_INCOMPLETE       0x00000100
#define FILE_VC_QUOTAS_REBUILDING       0x00000200
#define FILE_VC_VALID_MASK              0x000003ff

/* IOCTL code to impersonate client of named pipe. */

#define FSCTL_PIPE_DISCONNECT	CTL_CODE(FILE_DEVICE_NAMED_PIPE, 1, \
					 METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_LISTEN	CTL_CODE(FILE_DEVICE_NAMED_PIPE, 2, \
					METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_PEEK		CTL_CODE(FILE_DEVICE_NAMED_PIPE, 3, \
					 METHOD_BUFFERED, FILE_READ_DATA)
#define FSCTL_PIPE_WAIT		CTL_CODE(FILE_DEVICE_NAMED_PIPE, 6, \
					 METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_IMPERSONATE	CTL_CODE(FILE_DEVICE_NAMED_PIPE, 7, \
					 METHOD_BUFFERED, FILE_ANY_ACCESS)
#define FSCTL_PIPE_FLUSH	CTL_CODE(FILE_DEVICE_NAMED_PIPE, 16, \
					 METHOD_BUFFERED, FILE_WRITE_DATA)

typedef enum _FILE_INFORMATION_CLASS
{
  FileDirectoryInformation = 1,			//  1
  FileFullDirectoryInformation,			//  2
  FileBothDirectoryInformation,			//  3
  FileBasicInformation,				//  4
  FileStandardInformation,			//  5
  FileInternalInformation,			//  6
  FileEaInformation,				//  7
  FileAccessInformation,			//  8
  FileNameInformation,				//  9
  FileRenameInformation,			// 10
  FileLinkInformation,				// 11
  FileNamesInformation,				// 12
  FileDispositionInformation,			// 13
  FilePositionInformation,			// 14
  FileFullEaInformation,			// 15
  FileModeInformation,				// 16
  FileAlignmentInformation,			// 17
  FileAllInformation,				// 18
  FileAllocationInformation,			// 19
  FileEndOfFileInformation,			// 20
  FileAlternateNameInformation,			// 21
  FileStreamInformation,			// 22
  FilePipeInformation,				// 23
  FilePipeLocalInformation,			// 24
  FilePipeRemoteInformation,			// 25
  FileMailslotQueryInformation,			// 26
  FileMailslotSetInformation,			// 27
  FileCompressionInformation,			// 28
  FileObjectIdInformation,			// 29
  FileCompletionInformation,			// 30
  FileMoveClusterInformation,			// 31
  FileQuotaInformation,				// 32
  FileReparsePointInformation,			// 33
  FileNetworkOpenInformation,			// 34
  FileAttributeTagInformation,			// 35
  FileTrackingInformation,			// 36
  FileIdBothDirectoryInformation,		// 37
  FileIdFullDirectoryInformation,		// 38
  FileValidDataLengthInformation,		// 39
  FileShortNameInformation,			// 40
  FileIoCompletionNotificationInformation,	// 41
  FileIoStatusBlockRangeInformation,		// 42
  FileIoPriorityHintInformation,		// 43
  FileSfioReserveInformation,			// 44
  FileSfioVolumeInformation,			// 45
  FileHardLinkInformation,			// 46
  FileProcessIdsUsingFileInformation,		// 47
  FileNormalizedNameInformation,		// 48
  FileNetworkPhysicalNameInformation,		// 49
  FileIdGlobalTxDirectoryInformation,		// 50
  FileIsRemoteDeviceInformation,		// 51
  FileUnusedInformation,			// 52
  FileNumaNodeInformation,			// 53
  FileStandardLinkInformation,			// 54
  FileRemoteProtocolInformation,		// 55
  FileRenameInformationBypassAccessCheck,	// 56
  FileLinkInformationBypassAccessCheck,		// 57
  FileVolumeNameInformation,			// 58
  FileIdInformation,				// 59
  FileIdExtdDirectoryInformation,		// 60
  FileReplaceCompletionInformation,		// 61
  FileHardLinkFullIdInformation,		// 62
  FileIdExtdBothDirectoryInformation,		// 63
  FileDispositionInformationEx,			// 64
  FileRenameInformationEx,			// 65
  FileRenameInformationExBypassAccessCheck,	// 66
  FileDesiredStorageClassInformation,		// 67
  FileStatInformation,				// 68
  FileMemoryPartitionInformation,		// 69
  FileStatLxInformation,			// 70
  FileCaseSensitiveInformation,			// 71
  FileLinkInformationEx,			// 72
  FileLinkInformationExBypassAccessCheck,	// 73
  FileStorageReserveIdInformation,		// 74
  FileCaseSensitiveInformationForceAccessCheck,	// 75
  FileMaximumInformation
} FILE_INFORMATION_CLASS, *PFILE_INFORMATION_CLASS;

typedef struct _FILE_DIRECTORY_INFORMATION	//  1
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  WCHAR  FileName[1];
} FILE_DIRECTORY_INFORMATION, *PFILE_DIRECTORY_INFORMATION;

typedef struct _FILE_BOTH_DIR_INFORMATION	//  3
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  ULONG  EaSize;
  CCHAR  ShortNameLength;
  WCHAR  ShortName[12];
  WCHAR  FileName[1];
} FILE_BOTH_DIR_INFORMATION, *PFILE_BOTH_DIR_INFORMATION;

typedef struct _FILE_BASIC_INFORMATION		//  4
{
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  ULONG FileAttributes;
} FILE_BASIC_INFORMATION, *PFILE_BASIC_INFORMATION;

typedef struct _FILE_STANDARD_INFORMATION	//  5
{
  LARGE_INTEGER AllocationSize;
  LARGE_INTEGER EndOfFile;
  ULONG NumberOfLinks;
  BOOLEAN DeletePending;
  BOOLEAN Directory;
} FILE_STANDARD_INFORMATION, *PFILE_STANDARD_INFORMATION;

typedef struct _FILE_INTERNAL_INFORMATION	//  6
{
  LARGE_INTEGER IndexNumber;
} FILE_INTERNAL_INFORMATION, *PFILE_INTERNAL_INFORMATION;

typedef struct _FILE_EA_INFORMATION		//  7
{
  ULONG EaSize;
} FILE_EA_INFORMATION, *PFILE_EA_INFORMATION;

typedef struct _FILE_ACCESS_INFORMATION		//  8
{
  ACCESS_MASK AccessFlags;
} FILE_ACCESS_INFORMATION, *PFILE_ACCESS_INFORMATION;

typedef struct _FILE_NAME_INFORMATION		//  9, 21, 40
{
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_NAME_INFORMATION, *PFILE_NAME_INFORMATION;

typedef struct _FILE_RENAME_INFORMATION		// 10, 56, 65, 66
{
  union
  {
    BOOLEAN ReplaceIfExists;	// FileRenameInformation
    ULONG Flags;		// FileRenameInformationEx
  };
  HANDLE RootDirectory;
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_RENAME_INFORMATION, *PFILE_RENAME_INFORMATION;

typedef struct _FILE_LINK_INFORMATION		// 11, 57, 72, 73
{
  union
  {
    BOOLEAN ReplaceIfExists;	// FileLinkInformation
    ULONG Flags;		// FileLinkInformationEx
  };
  HANDLE RootDirectory;
  ULONG FileNameLength;
  WCHAR FileName[1];
} FILE_LINK_INFORMATION, *PFILE_LINK_INFORMATION;

typedef struct _FILE_NAMES_INFORMATION		// 12
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  ULONG  FileNameLength;
  WCHAR  FileName[1];
} FILE_NAMES_INFORMATION, *PFILE_NAMES_INFORMATION;

typedef struct _FILE_DISPOSITION_INFORMATION	// 13
{
  BOOLEAN DeleteFile;
} FILE_DISPOSITION_INFORMATION, *PFILE_DISPOSITION_INFORMATION;

typedef struct _FILE_POSITION_INFORMATION	// 14
{
  LARGE_INTEGER CurrentByteOffset;
} FILE_POSITION_INFORMATION, *PFILE_POSITION_INFORMATION;

typedef struct _FILE_MODE_INFORMATION		// 16
{
  ULONG Mode;
} FILE_MODE_INFORMATION, *PFILE_MODE_INFORMATION;

typedef struct _FILE_ALIGNMENT_INFORMATION	// 17
{
  ULONG AlignmentRequirement;
} FILE_ALIGNMENT_INFORMATION;

typedef struct _FILE_ALL_INFORMATION {		// 18
  FILE_BASIC_INFORMATION     BasicInformation;
  FILE_STANDARD_INFORMATION  StandardInformation;
  FILE_INTERNAL_INFORMATION  InternalInformation;
  FILE_EA_INFORMATION        EaInformation;
  FILE_ACCESS_INFORMATION    AccessInformation;
  FILE_POSITION_INFORMATION  PositionInformation;
  FILE_MODE_INFORMATION      ModeInformation;
  FILE_ALIGNMENT_INFORMATION AlignmentInformation;
  FILE_NAME_INFORMATION      NameInformation;
} FILE_ALL_INFORMATION, *PFILE_ALL_INFORMATION;

typedef struct _FILE_END_OF_FILE_INFORMATION	// 20
{
  LARGE_INTEGER EndOfFile;
} FILE_END_OF_FILE_INFORMATION, *PFILE_END_OF_FILE_INFORMATION;

typedef struct _FILE_PIPE_INFORMATION		// 23
{
  ULONG ReadMode;
  ULONG CompletionMode;
} FILE_PIPE_INFORMATION, *PFILE_PIPE_INFORMATION;

typedef struct _FILE_PIPE_LOCAL_INFORMATION	// 24
{
  ULONG NamedPipeType;
  ULONG NamedPipeConfiguration;
  ULONG MaximumInstances;
  ULONG CurrentInstances;
  ULONG InboundQuota;
  ULONG ReadDataAvailable;
  ULONG OutboundQuota;
  ULONG WriteQuotaAvailable;
  ULONG NamedPipeState;
  ULONG NamedPipeEnd;
} FILE_PIPE_LOCAL_INFORMATION, *PFILE_PIPE_LOCAL_INFORMATION;

typedef struct _FILE_COMPRESSION_INFORMATION	// 28
{
  LARGE_INTEGER CompressedFileSize;
  USHORT CompressionFormat;
  UCHAR	CompressionUnitShift;
  UCHAR ChunkShift;
  UCHAR ClusterShift;
  UCHAR Reserved[3];
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;

typedef struct _FILE_NETWORK_OPEN_INFORMATION	// 34
{
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  LARGE_INTEGER AllocationSize;
  LARGE_INTEGER EndOfFile;
  ULONG FileAttributes;
} FILE_NETWORK_OPEN_INFORMATION, *PFILE_NETWORK_OPEN_INFORMATION;

typedef struct _FILE_ID_BOTH_DIR_INFORMATION	// 37
{
  ULONG  NextEntryOffset;
  ULONG  FileIndex;
  LARGE_INTEGER  CreationTime;
  LARGE_INTEGER  LastAccessTime;
  LARGE_INTEGER  LastWriteTime;
  LARGE_INTEGER  ChangeTime;
  LARGE_INTEGER  EndOfFile;
  LARGE_INTEGER  AllocationSize;
  ULONG  FileAttributes;
  ULONG  FileNameLength;
  ULONG  EaSize;
  CCHAR  ShortNameLength;
  WCHAR  ShortName[12];
  LARGE_INTEGER  FileId;
  WCHAR  FileName[1];
} FILE_ID_BOTH_DIR_INFORMATION, *PFILE_ID_BOTH_DIR_INFORMATION;

typedef struct _FILE_PROCESS_IDS_USING_FILE_INFORMATION	// 47
{
  ULONG NumberOfProcessIdsInList;
  ULONG_PTR ProcessIdList[1];
} FILE_PROCESS_IDS_USING_FILE_INFORMATION,
  *PFILE_PROCESS_IDS_USING_FILE_INFORMATION;

typedef struct _FILE_DISPOSITION_INFORMATION_EX	// 64
{
  ULONG Flags;
} FILE_DISPOSITION_INFORMATION_EX, *PFILE_DISPOSITION_INFORMATION_EX;

typedef struct _FILE_STAT_INFORMATION		// 68
{
  LARGE_INTEGER FileId;
  LARGE_INTEGER CreationTime;
  LARGE_INTEGER LastAccessTime;
  LARGE_INTEGER LastWriteTime;
  LARGE_INTEGER ChangeTime;
  LARGE_INTEGER AllocationSize;
  LARGE_INTEGER EndOfFile;
  ULONG FileAttributes;
  ULONG ReparseTag;
  ULONG NumberOfLinks;
  ACCESS_MASK EffectiveAccess;
} FILE_STAT_INFORMATION, *PFILE_STAT_INFORMATION;

typedef struct _FILE_CASE_SENSITIVE_INFORMATION	// 71
{
  ULONG Flags;
} FILE_CASE_SENSITIVE_INFORMATION, *PFILE_CASE_SENSITIVE_INFORMATION;

enum {
  FILE_LINK_REPLACE_IF_EXISTS				= 0x01,
  FILE_LINK_POSIX_SEMANTICS				= 0x02,
  FILE_LINK_SUPPRESS_STORAGE_RESERVE_INHERITANCE	= 0x08,
  FILE_LINK_NO_INCREASE_AVAILABLE_SPACE			= 0x10,
  FILE_LINK_NO_DECREASE_AVAILABLE_SPACE			= 0x20,
  FILE_LINK_PRESERVE_AVAILABLE_SPACE			= 0x30,
  FILE_LINK_IGNORE_READONLY_ATTRIBUTE			= 0x40
};

enum {
  FILE_DISPOSITION_DO_NOT_DELETE			= 0x00,
  FILE_DISPOSITION_DELETE				= 0x01,
  FILE_DISPOSITION_POSIX_SEMANTICS			= 0x02,
  FILE_DISPOSITION_FORCE_IMAGE_SECTION_CHECK		= 0x04,
  FILE_DISPOSITION_ON_CLOSE				= 0x08
};

enum
{
  FILE_RENAME_REPLACE_IF_EXISTS				= 0x01,
  FILE_RENAME_POSIX_SEMANTICS				= 0x02,
  FILE_RENAME_SUPPRESS_PIN_STATE_INHERITANCE		= 0x04,
  FILE_RENAME_SUPPRESS_STORAGE_RESERVE_INHERITANCE	= 0x08,
  FILE_RENAME_NO_INCREASE_AVAILABLE_SPACE		= 0x10,
  FILE_RENAME_NO_DECREASE_AVAILABLE_SPACE		= 0x20,
  FILE_RENAME_PRESERVE_AVAILABLE_SPACE			= 0x30,
  FILE_RENAME_IGNORE_READONLY_ATTRIBUTE			= 0x40
};

enum
{
  FILE_CS_FLAG_CASE_SENSITIVE_DIR			= 0x01
};

enum
{
  FILE_PIPE_QUEUE_OPERATION = 0,
  FILE_PIPE_COMPLETE_OPERATION = 1
};

enum
{
  FILE_PIPE_BYTE_STREAM_MODE = 0,
  FILE_PIPE_MESSAGE_MODE = 1
};

enum
{
  FILE_PIPE_DISCONNECTED_STATE = 1,
  FILE_PIPE_LISTENING_STATE = 2,
  FILE_PIPE_CONNECTED_STATE = 3,
  FILE_PIPE_CLOSING_STATE = 4
};

enum
{
  FILE_PIPE_INBOUND = 0,
  FILE_PIPE_OUTBOUND = 1,
  FILE_PIPE_FULL_DUPLEX = 2
};

enum
{
  FILE_PIPE_CLIENT_END = 0,
  FILE_PIPE_SERVER_END = 1
};

enum
{
  FILE_PIPE_BYTE_STREAM_TYPE = 0,
  FILE_PIPE_MESSAGE_TYPE = 1,
  FILE_PIPE_REJECT_REMOTE_CLIENTS = 2
};

typedef struct _FILE_PIPE_PEEK_BUFFER {
  ULONG NamedPipeState;
  ULONG ReadDataAvailable;
  ULONG NumberOfMessages;
  ULONG MessageLength;
  CHAR Data[1];
} FILE_PIPE_PEEK_BUFFER, *PFILE_PIPE_PEEK_BUFFER;

typedef struct _FILE_PIPE_WAIT_FOR_BUFFER {
  LARGE_INTEGER Timeout;
  ULONG NameLength;
  BOOLEAN TimeoutSpecified;
  WCHAR Name[1];
} FILE_PIPE_WAIT_FOR_BUFFER, *PFILE_PIPE_WAIT_FOR_BUFFER;

typedef enum _SYSTEM_INFORMATION_CLASS
{
  SystemBasicInformation = 0,
  SystemPerformanceInformation = 2,
  SystemTimeOfDayInformation = 3,
  SystemProcessInformation = 5,
  SystemProcessorPerformanceInformation = 8,
  SystemHandleInformation = 16,
  SystemPagefileInformation = 18,
  SystemProcessIdInformation = 0x58,
  /* There are a lot more of these... */
} SYSTEM_INFORMATION_CLASS;

typedef struct _SYSTEM_BASIC_INFORMATION
{
  ULONG Unknown;
  ULONG MaximumIncrement;
  ULONG PhysicalPageSize;
  ULONG NumberOfPhysicalPages;
  ULONG LowestPhysicalPage;
  ULONG HighestPhysicalPage;
  ULONG AllocationGranularity;
  ULONG_PTR LowestUserAddress;
  ULONG_PTR HighestUserAddress;
  ULONG_PTR ActiveProcessors;
  UCHAR NumberProcessors;
} SYSTEM_BASIC_INFORMATION, *PSYSTEM_BASIC_INFORMATION;

typedef struct _SYSTEM_PAGEFILE_INFORMATION
{
  ULONG NextEntryOffset;
  ULONG CurrentSize;
  ULONG TotalUsed;
  ULONG PeakUsed;
  UNICODE_STRING FileName;
} SYSTEM_PAGEFILE_INFORMATION, *PSYSTEM_PAGEFILE_INFORMATION;

typedef struct _SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER IdleTime;
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER DpcTime;
  LARGE_INTEGER InterruptTime;
  ULONG InterruptCount;
} SYSTEM_PROCESSOR_PERFORMANCE_INFORMATION, *PSYSTEM_PROCESSOR_PERFORMANCE_INFORMATION;

typedef LONG KPRIORITY;

typedef struct _VM_COUNTERS
{
  SIZE_T PeakVirtualSize;
  SIZE_T VirtualSize;
  ULONG PageFaultCount;
  SIZE_T PeakWorkingSetSize;
  SIZE_T WorkingSetSize;
  SIZE_T QuotaPeakPagedPoolUsage;
  SIZE_T QuotaPagedPoolUsage;
  SIZE_T QuotaPeakNonPagedPoolUsage;
  SIZE_T QuotaNonPagedPoolUsage;
  SIZE_T PagefileUsage;
  SIZE_T PeakPagefileUsage;
} VM_COUNTERS, *PVM_COUNTERS;

typedef struct _CLIENT_ID
{
  HANDLE UniqueProcess;
  HANDLE UniqueThread;
} CLIENT_ID, *PCLIENT_ID;

typedef enum
{
  StateInitialized,
  StateReady,
  StateRunning,
  StateStandby,
  StateTerminated,
  StateWait,
  StateTransition,
  StateUnknown,
} THREAD_STATE;

typedef enum
{
  Executive,
  FreePage,
  PageIn,
  PoolAllocation,
  DelayExecution,
  Suspended,
  UserRequest,
  WrExecutive,
  WrFreePage,
  WrPageIn,
  WrPoolAllocation,
  WrDelayExecution,
  WrSuspended,
  WrUserRequest,
  WrEventPair,
  WrQueue,
  WrLpcReceive,
  WrLpcReply,
  WrVirtualMemory,
  WrPageOut,
  WrRendezvous,
  Spare2,
  Spare3,
  Spare4,
  Spare5,
  Spare6,
  WrKernel,
  MaximumWaitReason
} KWAIT_REASON;

typedef struct _SYSTEM_THREADS
{
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER CreateTime;
  ULONG WaitTime;
  PVOID StartAddress;
  CLIENT_ID ClientId;
  KPRIORITY Priority;
  KPRIORITY BasePriority;
  ULONG ContextSwitchCount;
  THREAD_STATE State;
  KWAIT_REASON WaitReason;
  DWORD Reserved;
} SYSTEM_THREADS, *PSYSTEM_THREADS;

typedef struct _SYSTEM_PROCESS_INFORMATION
{
  ULONG NextEntryOffset;
  ULONG NumberOfThreads;
  ULONG Reserved1[6];
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER UserTime;
  LARGE_INTEGER KernelTime;
  UNICODE_STRING ImageName;
  KPRIORITY BasePriority;
  HANDLE UniqueProcessId;
  HANDLE InheritedFromUniqueProcessId;
  ULONG HandleCount;
  ULONG SessionId;
  ULONG PageDirectoryBase;
  VM_COUNTERS VirtualMemoryCounters;
  SIZE_T PrivatePageCount;
  IO_COUNTERS IoCounters;
  SYSTEM_THREADS Threads[1];
} SYSTEM_PROCESS_INFORMATION, *PSYSTEM_PROCESS_INFORMATION;

typedef struct _SYSTEM_PERFORMANCE_INFORMATION
{
  LARGE_INTEGER IdleTime;
  LARGE_INTEGER ReadTransferCount;
  LARGE_INTEGER WriteTransferCount;
  LARGE_INTEGER OtherTransferCount;
  ULONG ReadOperationCount;
  ULONG WriteOperationCount;
  ULONG OtherOperationCount;
  ULONG AvailablePages;
  ULONG TotalCommittedPages;
  ULONG TotalCommitLimit;
  ULONG PeakCommitment;
  ULONG PageFaults;
  ULONG WriteCopyFaults;
  ULONG TransitionFaults;
  ULONG Reserved1;
  ULONG DemandZeroFaults;
  ULONG PagesRead;
  ULONG PageReadIos;
  ULONG Reserved2[2];
  ULONG PagefilePagesWritten;
  ULONG PagefilePageWriteIos;
  ULONG MappedFilePagesWritten;
  ULONG MappedFilePageWriteIos;
  ULONG PagedPoolUsage;
  ULONG NonPagedPoolUsage;
  ULONG PagedPoolAllocs;
  ULONG PagedPoolFrees;
  ULONG NonPagedPoolAllocs;
  ULONG NonPagedPoolFrees;
  ULONG TotalFreeSystemPtes;
  ULONG SystemCodePage;
  ULONG TotalSystemDriverPages;
  ULONG TotalSystemCodePages;
  ULONG SmallNonPagedLookasideListAllocateHits;
  ULONG SmallPagedLookasideListAllocateHits;
  ULONG Reserved3;
  ULONG MmSystemCachePage;
  ULONG PagedPoolPage;
  ULONG SystemDriverPage;
  ULONG FastReadNoWait;
  ULONG FastReadWait;
  ULONG FastReadResourceMiss;
  ULONG FastReadNotPossible;
  ULONG FastMdlReadNoWait;
  ULONG FastMdlReadWait;
  ULONG FastMdlReadResourceMiss;
  ULONG FastMdlReadNotPossible;
  ULONG MapDataNoWait;
  ULONG MapDataWait;
  ULONG MapDataNoWaitMiss;
  ULONG MapDataWaitMiss;
  ULONG PinMappedDataCount;
  ULONG PinReadNoWait;
  ULONG PinReadWait;
  ULONG PinReadNoWaitMiss;
  ULONG PinReadWaitMiss;
  ULONG CopyReadNoWait;
  ULONG CopyReadWait;
  ULONG CopyReadNoWaitMiss;
  ULONG CopyReadWaitMiss;
  ULONG MdlReadNoWait;
  ULONG MdlReadWait;
  ULONG MdlReadNoWaitMiss;
  ULONG MdlReadWaitMiss;
  ULONG ReadAheadIos;
  ULONG LazyWriteIos;
  ULONG LazyWritePages;
  ULONG DataFlushes;
  ULONG DataPages;
  ULONG ContextSwitches;
  ULONG FirstLevelTbFills;
  ULONG SecondLevelTbFills;
  ULONG SystemCalls;
} SYSTEM_PERFORMANCE_INFORMATION, *PSYSTEM_PERFORMANCE_INFORMATION;

typedef struct _SYSTEM_TIMEOFDAY_INFORMATION
{
  LARGE_INTEGER BootTime;
  LARGE_INTEGER CurrentTime;
  LARGE_INTEGER TimeZoneBias;
  ULONG CurrentTimeZoneId;
  BYTE Reserved1[20];		/* Per MSDN.  Always 0. */
} SYSTEM_TIMEOFDAY_INFORMATION, *PSYSTEM_TIMEOFDAY_INFORMATION;

typedef struct _SYSTEM_PROCESS_ID_INFORMATION
{
  PVOID ProcessId;
  UNICODE_STRING ImageName;
} SYSTEM_PROCESS_ID_INFORMATION, *PSYSTEM_PROCESS_ID_INFORMATION;

typedef enum _PROCESSINFOCLASS
{
  ProcessBasicInformation = 0,
  ProcessQuotaLimits = 1,
  ProcessVmCounters = 3,
  ProcessTimes = 4,
  ProcessSessionInformation = 24,
  ProcessWow64Information = 26,
  ProcessImageFileName = 27,
  ProcessDebugFlags = 31
} PROCESSINFOCLASS;

typedef struct _DEBUG_BUFFER
{
  HANDLE SectionHandle;
  PVOID SectionBase;
  PVOID RemoteSectionBase;
  ULONG_PTR SectionBaseDelta;
  HANDLE EventPairHandle;
  ULONG_PTR Unknown[2];
  HANDLE RemoteThreadHandle;
  ULONG InfoClassMask;
  ULONG_PTR SizeOfInfo;
  ULONG_PTR AllocatedSize;
  ULONG_PTR SectionSize;
  PVOID ModuleInformation;
  PVOID BackTraceInformation;
  PVOID HeapInformation;
  PVOID LockInformation;
  PVOID Reserved[8];
} DEBUG_BUFFER, *PDEBUG_BUFFER;

typedef struct _DEBUG_HEAP_INFORMATION
{
  ULONG_PTR Base;
  ULONG Flags;
  USHORT Granularity;
  USHORT Unknown;
  ULONG_PTR Allocated;
  ULONG_PTR Committed;
  ULONG TagCount;
  ULONG BlockCount;
  ULONG Reserved[7];
  PVOID Tags;
  PVOID Blocks;
} DEBUG_HEAP_INFORMATION, *PDEBUG_HEAP_INFORMATION;

typedef struct _DEBUG_HEAP_ARRAY
{
  ULONG Count;
  DEBUG_HEAP_INFORMATION Heaps[1];
} DEBUG_HEAP_ARRAY, *PDEBUG_HEAP_ARRAY;

typedef struct _DEBUG_HEAP_BLOCK
{
  ULONG_PTR Size;
  ULONG Flags;
  ULONG_PTR Committed;
  ULONG_PTR Address;
} DEBUG_HEAP_BLOCK, *PDEBUG_HEAP_BLOCK;

typedef struct _DEBUG_MODULE_INFORMATION
{
  ULONG_PTR Reserved[2];
  ULONG_PTR Base;
  ULONG Size;
  ULONG Flags;
  USHORT Index;
  USHORT Unknown;
  USHORT LoadCount;
  USHORT ModuleNameOffset;
  CHAR ImageName[256];
} DEBUG_MODULE_INFORMATION, *PDEBUG_MODULE_INFORMATION;

typedef struct _DEBUG_MODULE_ARRAY
{
  ULONG Count;
  DEBUG_MODULE_INFORMATION Modules[1];
} DEBUG_MODULE_ARRAY, *PDEBUG_MODULE_ARRAY;

typedef struct _KERNEL_USER_TIMES
{
  LARGE_INTEGER CreateTime;
  LARGE_INTEGER ExitTime;
  LARGE_INTEGER KernelTime;
  LARGE_INTEGER UserTime;
} KERNEL_USER_TIMES, *PKERNEL_USER_TIMES;

typedef struct _LDR_DATA_TABLE_ENTRY
{
  /* Heads up!  The pointers within the LIST_ENTRYs don't point to the
     start of the next LDR_DATA_TABLE_ENTRY, but rather they point to the
     start of their respective LIST_ENTRY *within* LDR_DATA_TABLE_ENTRY. */
  LIST_ENTRY InLoadOrderLinks;
  LIST_ENTRY InMemoryOrderLinks;
  LIST_ENTRY InInitializationOrderLinks;
  PVOID DllBase;
  PVOID EntryPoint;
  ULONG SizeOfImage;
  UNICODE_STRING FullDllName;
  UNICODE_STRING BaseDllName;
  ULONG Flags;
  USHORT LoadCount;
  /* More follows.  Left out since it's just not used.  The aforementioned
     part of the structure is stable from at least NT4 up to Windows 8,
     including WOW64. */
} LDR_DATA_TABLE_ENTRY, *PLDR_DATA_TABLE_ENTRY;

typedef struct _PEB_LDR_DATA
{
  ULONG Length;
  BOOLEAN Initialized;
  PVOID SsHandle;
  /* Heads up!  The pointers within the LIST_ENTRYs don't point to the
     start of the next LDR_DATA_TABLE_ENTRY, but rather they point to the
     start of their respective LIST_ENTRY *within* LDR_DATA_TABLE_ENTRY. */
  LIST_ENTRY InLoadOrderModuleList;
  LIST_ENTRY InMemoryOrderModuleList;
  LIST_ENTRY InInitializationOrderModuleList;
  PVOID EntryInProgress;
} PEB_LDR_DATA, *PPEB_LDR_DATA;

typedef struct _RTL_USER_PROCESS_PARAMETERS
{
  ULONG AllocationSize;
  ULONG Size;
  ULONG Flags;
  ULONG DebugFlags;
  HANDLE hConsole;
  ULONG ProcessGroup;
  HANDLE hStdInput;
  HANDLE hStdOutput;
  HANDLE hStdError;
  UNICODE_STRING CurrentDirectoryName;
  HANDLE CurrentDirectoryHandle;
  UNICODE_STRING DllPath;
  UNICODE_STRING ImagePathName;
  UNICODE_STRING CommandLine;
  PWSTR Environment;
  ULONG dwX;
  ULONG dwY;
  ULONG dwXSize;
  ULONG dwYSize;
  ULONG dwXCountChars;
  ULONG dwYCountChars;
  ULONG dwFillAttribute;
  ULONG dwFlags;
  ULONG wShowWindow;
  UNICODE_STRING WindowTitle;
  UNICODE_STRING DesktopInfo;
  UNICODE_STRING ShellInfo;
  UNICODE_STRING RuntimeInfo;
} RTL_USER_PROCESS_PARAMETERS, *PRTL_USER_PROCESS_PARAMETERS;

typedef struct _PEB
{
  BYTE Reserved1[2];
  BYTE BeingDebugged;
  BYTE Reserved2[1];
  PVOID Reserved3[2];
  PPEB_LDR_DATA Ldr;
  PRTL_USER_PROCESS_PARAMETERS ProcessParameters;
  PVOID Reserved4;
  PVOID ProcessHeap;
  PRTL_CRITICAL_SECTION FastPebLock;
  PVOID Reserved5[2];
  ULONG EnvironmentUpdateCount;
  BYTE Reserved6[228];
  PVOID Reserved7[49];
  ULONG SessionId;
  /* A lot more follows... */
} PEB, *PPEB;

typedef struct _GDI_TEB_BATCH
{
  ULONG Offset;
  HANDLE HDC;
  ULONG Buffer[0x136];
} GDI_TEB_BATCH, *PGDI_TEB_BATCH;

typedef struct _TEB
{
  NT_TIB Tib;
  PVOID EnvironmentPointer;
  CLIENT_ID ClientId;
  PVOID ActiveRpcHandle;
  PVOID ThreadLocalStoragePointer;
  PPEB Peb;
  ULONG LastErrorValue;
  ULONG CountOfOwnedCriticalSections;
  PVOID CsrClientThread;
  PVOID Win32ThreadInfo;
  ULONG User32Reserved[26];
  ULONG UserReserved[5];
  PVOID WOW32Reserved;
  LCID CurrentLocale;
  ULONG FpSoftwareStatusRegister;
  PVOID SystemReserved1[54];
  LONG ExceptionCode;
  PVOID ActivationContextStackPointer;
  UCHAR SpareBytes1[0x30 - 3 * sizeof(PVOID)];
  ULONG TxFsContext;
  GDI_TEB_BATCH GdiTebBatch;
  CLIENT_ID RealClientId;
  PVOID GdiCachedProcessHandle;
  ULONG GdiClientPID;
  ULONG GdiClientTID;
  PVOID GdiThreadLocalInfo;
  SIZE_T Win32ClientInfo[62];
  PVOID glDispatchTable[233];
  SIZE_T glReserved1[29];
  PVOID glReserved2;
  PVOID glSectionInfo;
  PVOID glSection;
  PVOID glTable;
  PVOID glCurrentRC;
  PVOID glContext;
  ULONG LastStatusValue;
  UNICODE_STRING StaticUnicodeString;
  WCHAR StaticUnicodeBuffer[261];
  PVOID DeallocationStack;
  PVOID TlsSlots[64];
  BYTE Reserved3[8];
  PVOID Reserved4[26];
  PVOID ReservedForOle;
  PVOID Reserved5[4];
  PVOID TlsExpansionSlots;
  /* A lot more follows... */
} TEB, *PTEB;

typedef struct _KSYSTEM_TIME
{
  ULONG LowPart;
  LONG High1Time;
  LONG High2Time;
} KSYSTEM_TIME, *PKSYSTEM_TIME;

typedef struct _KUSER_SHARED_DATA
{
  BYTE Reserved1[0x08];
  KSYSTEM_TIME InterruptTime;
  BYTE Reserved2[0x2c8];
  ULONG DismountCount;
  BYTE Reserved3[0xd0];
  UINT64 InterruptTimeBias;
} KUSER_SHARED_DATA, *PKUSER_SHARED_DATA;

typedef struct _PROCESS_BASIC_INFORMATION
{
  NTSTATUS ExitStatus;
  PPEB PebBaseAddress;
  KAFFINITY AffinityMask;
  KPRIORITY BasePriority;	/* !!!Broken on WOW64!!! */
  ULONG_PTR UniqueProcessId;
  ULONG_PTR InheritedFromUniqueProcessId;
} PROCESS_BASIC_INFORMATION, *PPROCESS_BASIC_INFORMATION;

typedef struct _PROCESS_SESSION_INFORMATION
{
  ULONG  SessionId;
} PROCESS_SESSION_INFORMATION, *PPROCESS_SESSION_INFORMATION;

typedef enum _MEMORY_INFORMATION_CLASS
{
  MemoryBasicInformation,
  MemoryWorkingSetList,
  MemorySectionName,
  MemoryBasicVlmInformation
} MEMORY_INFORMATION_CLASS;

typedef struct _MEMORY_WORKING_SET_LIST
{
  ULONG NumberOfPages;
  ULONG_PTR WorkingSetList[1];
} MEMORY_WORKING_SET_LIST, *PMEMORY_WORKING_SET_LIST;

typedef struct _MEMORY_SECTION_NAME
{
  UNICODE_STRING SectionFileName;
} MEMORY_SECTION_NAME, *PMEMORY_SECTION_NAME;

typedef struct _FILE_FS_DEVICE_INFORMATION
{
  ULONG DeviceType;
  ULONG Characteristics;
} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;

typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
{
  ULONG FileSystemAttributes;
  ULONG MaximumComponentNameLength;
  ULONG FileSystemNameLength;
  WCHAR FileSystemName[1];
} FILE_FS_ATTRIBUTE_INFORMATION, *PFILE_FS_ATTRIBUTE_INFORMATION;

#pragma pack(push,4)
typedef struct _FILE_FS_VOLUME_INFORMATION
{
  LARGE_INTEGER VolumeCreationTime;
  ULONG VolumeSerialNumber;
  ULONG VolumeLabelLength;
  BOOLEAN SupportsObjects;
  BOOLEAN __dummy;
  WCHAR VolumeLabel[1];
} FILE_FS_VOLUME_INFORMATION, *PFILE_FS_VOLUME_INFORMATION;
#pragma pack(pop)

typedef struct _FILE_FS_SIZE_INFORMATION
{
  LARGE_INTEGER TotalAllocationUnits;
  LARGE_INTEGER AvailableAllocationUnits;
  ULONG SectorsPerAllocationUnit;
  ULONG BytesPerSector;
} FILE_FS_SIZE_INFORMATION, *PFILE_FS_SIZE_INFORMATION;

typedef struct _FILE_FS_CONTROL_INFORMATION {
  LARGE_INTEGER FreeSpaceStartFiltering;
  LARGE_INTEGER FreeSpaceThreshold;
  LARGE_INTEGER FreeSpaceStopFiltering;
  LARGE_INTEGER DefaultQuotaThreshold;
  LARGE_INTEGER DefaultQuotaLimit;
  ULONG FileSystemControlFlags;
} FILE_FS_CONTROL_INFORMATION, *PFILE_FS_CONTROL_INFORMATION;

typedef struct _FILE_FS_FULL_SIZE_INFORMATION
{
  LARGE_INTEGER TotalAllocationUnits;
  LARGE_INTEGER CallerAvailableAllocationUnits;
  LARGE_INTEGER ActualAvailableAllocationUnits;
  ULONG SectorsPerAllocationUnit;
  ULONG BytesPerSector;
} FILE_FS_FULL_SIZE_INFORMATION, *PFILE_FS_FULL_SIZE_INFORMATION;

typedef struct _FILE_FS_OBJECTID_INFORMATION
{
  UCHAR ObjectId[16];
  UCHAR ExtendedInfo[48];
} FILE_FS_OBJECTID_INFORMATION, *PFILE_FS_OBJECTID_INFORMATION;

typedef enum _FSINFOCLASS {
  FileFsVolumeInformation = 1,
  FileFsLabelInformation,
  FileFsSizeInformation,
  FileFsDeviceInformation,
  FileFsAttributeInformation,
  FileFsControlInformation,
  FileFsFullSizeInformation,
  FileFsObjectIdInformation,
  FileFsDriverPathInformation,
  FileFsMaximumInformation
} FS_INFORMATION_CLASS, *PFS_INFORMATION_CLASS;

typedef enum _OBJECT_INFORMATION_CLASS
{
  ObjectBasicInformation = 0,
  ObjectNameInformation = 1,
  ObjectHandleInformation = 4
   // and many more
} OBJECT_INFORMATION_CLASS;

typedef struct _OBJECT_BASIC_INFORMATION
{
  ULONG Attributes;
  ACCESS_MASK GrantedAccess;
  ULONG HandleCount;
  ULONG PointerCount;
  ULONG PagedPoolUsage;
  ULONG NonPagedPoolUsage;
  ULONG Reserved[3];
  ULONG NameInformationLength;
  ULONG TypeInformationLength;
  ULONG SecurityDescriptorLength;
  LARGE_INTEGER CreateTime;
} OBJECT_BASIC_INFORMATION, *POBJECT_BASIC_INFORMATION;

typedef struct _OBJECT_NAME_INFORMATION
{
  UNICODE_STRING Name;
} OBJECT_NAME_INFORMATION;

typedef struct _DIRECTORY_BASIC_INFORMATION
{
  UNICODE_STRING ObjectName;
  UNICODE_STRING ObjectTypeName;
} DIRECTORY_BASIC_INFORMATION, *PDIRECTORY_BASIC_INFORMATION;

typedef struct _FILE_GET_QUOTA_INFORMATION {
  ULONG NextEntryOffset;
  ULONG SidLength;
  SID Sid;
} FILE_GET_QUOTA_INFORMATION, *PFILE_GET_QUOTA_INFORMATION;

typedef struct _FILE_QUOTA_INFORMATION {
  ULONG NextEntryOffset;
  ULONG SidLength;
  LARGE_INTEGER ChangeTime;
  LARGE_INTEGER QuotaUsed;
  LARGE_INTEGER QuotaThreshold;
  LARGE_INTEGER QuotaLimit;
  SID Sid;
} FILE_QUOTA_INFORMATION, *PFILE_QUOTA_INFORMATION;

typedef struct _FILE_GET_EA_INFORMATION
{
  ULONG NextEntryOffset;
  UCHAR EaNameLength;
  CHAR EaName[1];
} FILE_GET_EA_INFORMATION, *PFILE_GET_EA_INFORMATION;

typedef struct _FILE_FULL_EA_INFORMATION
{
  ULONG NextEntryOffset;
  UCHAR Flags;
  UCHAR EaNameLength;
  USHORT EaValueLength;
  CHAR EaName[1];
} FILE_FULL_EA_INFORMATION, *PFILE_FULL_EA_INFORMATION;

typedef struct _FILE_MAILSLOT_SET_INFORMATION
{
  LARGE_INTEGER ReadTimeout;
} FILE_MAILSLOT_SET_INFORMATION, *PFILE_MAILSLOT_SET_INFORMATION;

typedef struct _IO_STATUS_BLOCK
{
  union {
    NTSTATUS Status;
    PVOID Pointer;
  };
  ULONG_PTR Information;
} IO_STATUS_BLOCK, *PIO_STATUS_BLOCK;

typedef VOID NTAPI (*PIO_APC_ROUTINE)(PVOID, PIO_STATUS_BLOCK, ULONG);

typedef struct _EVENT_BASIC_INFORMATION
{
  EVENT_TYPE EventType;
  LONG SignalState;
} EVENT_BASIC_INFORMATION, *PEVENT_BASIC_INFORMATION;

typedef enum _EVENT_INFORMATION_CLASS
{
  EventBasicInformation = 0
} EVENT_INFORMATION_CLASS, *PEVENT_INFORMATION_CLASS;

typedef struct _SEMAPHORE_BASIC_INFORMATION
{
  LONG CurrentCount;
  LONG MaximumCount;
} SEMAPHORE_BASIC_INFORMATION, *PSEMAPHORE_BASIC_INFORMATION;

typedef enum _SEMAPHORE_INFORMATION_CLASS
{
  SemaphoreBasicInformation = 0
} SEMAPHORE_INFORMATION_CLASS, *PSEMAPHORE_INFORMATION_CLASS;

typedef enum _THREADINFOCLASS
{
  ThreadBasicInformation = 0,
  ThreadTimes = 1,
  ThreadImpersonationToken = 5,
  ThreadQuerySetWin32StartAddress = 9
} THREADINFOCLASS, *PTHREADINFOCLASS;

typedef struct _THREAD_BASIC_INFORMATION
{
  NTSTATUS ExitStatus;
  PNT_TIB TebBaseAddress;
  CLIENT_ID ClientId;
  KAFFINITY AffinityMask;
  KPRIORITY Priority;
  KPRIORITY BasePriority;
} THREAD_BASIC_INFORMATION, *PTHREAD_BASIC_INFORMATION;

typedef enum _TIMER_INFORMATION_CLASS {
  TimerBasicInformation = 0
} TIMER_INFORMATION_CLASS, *PTIMER_INFORMATION_CLASS;

typedef struct _TIMER_BASIC_INFORMATION {
  LARGE_INTEGER TimeRemaining;
  BOOLEAN SignalState;
} TIMER_BASIC_INFORMATION, *PTIMER_BASIC_INFORMATION;

typedef NTSTATUS (*PRTL_QUERY_REGISTRY_ROUTINE)
		 (PWSTR, ULONG, PVOID, ULONG, PVOID, PVOID);

typedef struct _RTL_QUERY_REGISTRY_TABLE
{
  PRTL_QUERY_REGISTRY_ROUTINE QueryRoutine;
  ULONG Flags;
  PCWSTR Name;
  PVOID EntryContext;
  ULONG DefaultType;
  PVOID DefaultData;
  ULONG DefaultLength;
} RTL_QUERY_REGISTRY_TABLE, *PRTL_QUERY_REGISTRY_TABLE;

typedef enum _KEY_VALUE_INFORMATION_CLASS
{
  KeyValueBasicInformation = 0,
  KeyValueFullInformation,
  KeyValuePartialInformation
} KEY_VALUE_INFORMATION_CLASS, *PKEY_VALUE_INFORMATION_CLASS;

typedef struct _KEY_VALUE_PARTIAL_INFORMATION
{
  ULONG TitleIndex;
  ULONG Type;
  ULONG DataLength;
  UCHAR Data[1];
} KEY_VALUE_PARTIAL_INFORMATION, *PKEY_VALUE_PARTIAL_INFORMATION;

typedef enum _SECTION_INHERIT
{
  ViewShare = 1,
  ViewUnmap = 2
} SECTION_INHERIT;

typedef VOID (APIENTRY *PTIMER_APC_ROUTINE)(PVOID, ULONG, ULONG);

#ifdef __x86_64__
typedef struct _SCOPE_TABLE
{
  ULONG Count;
  struct
  {
    ULONG BeginAddress;
    ULONG EndAddress;
    ULONG HandlerAddress;
    ULONG JumpTarget;
  } ScopeRecord[1];
} SCOPE_TABLE, *PSCOPE_TABLE;
#endif

#ifdef __cplusplus
/* This is the mapping of the KUSER_SHARED_DATA structure into the user
   address space on BOTH architectures, 32 and 64 bit!
   We need it here to access the current DismountCount and InterruptTime.  */
static volatile KUSER_SHARED_DATA &SharedUserData
	= *(volatile KUSER_SHARED_DATA *) 0x7ffe0000;

/* Function declarations for ntdll.dll.  These don't appear in any
   standard Win32 header.  */

extern "C"
{
#endif
  NTSTATUS NTAPI NtAccessCheck (PSECURITY_DESCRIPTOR, HANDLE, ACCESS_MASK,
				PGENERIC_MAPPING, PPRIVILEGE_SET, PULONG,
				PACCESS_MASK, PNTSTATUS);
  NTSTATUS NTAPI NtAdjustPrivilegesToken (HANDLE, BOOLEAN, PTOKEN_PRIVILEGES,
					  ULONG, PTOKEN_PRIVILEGES, PULONG);
  NTSTATUS NTAPI NtAllocateLocallyUniqueId (PLUID);
  NTSTATUS NTAPI NtAllocateUuids (PLARGE_INTEGER, PULONG, PULONG, PUCHAR);
  NTSTATUS NTAPI NtCancelTimer (HANDLE, PBOOLEAN);
  NTSTATUS NTAPI NtClose (HANDLE);
  NTSTATUS NTAPI NtCommitTransaction (HANDLE, BOOLEAN);
  NTSTATUS NTAPI NtContinue (PCONTEXT, BOOLEAN);
  NTSTATUS NTAPI NtCreateDirectoryObject (PHANDLE, ACCESS_MASK,
					  POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtCreateKey (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES, ULONG,
			      PUNICODE_STRING, ULONG, PULONG);
  NTSTATUS NTAPI NtCreateEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				EVENT_TYPE, BOOLEAN);
  NTSTATUS NTAPI NtCreateFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
			     PIO_STATUS_BLOCK, PLARGE_INTEGER, ULONG, ULONG,
			     ULONG, ULONG, PVOID, ULONG);
  NTSTATUS NTAPI NtCreateMailslotFile(PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				      PIO_STATUS_BLOCK, ULONG, ULONG, ULONG,
				      PLARGE_INTEGER);
  NTSTATUS NTAPI NtCreateMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				 BOOLEAN);
  NTSTATUS NTAPI NtCreateNamedPipeFile (PHANDLE, ACCESS_MASK,
					POBJECT_ATTRIBUTES, PIO_STATUS_BLOCK,
					ULONG, ULONG, ULONG, ULONG, ULONG,
					ULONG, ULONG, ULONG, ULONG,
					PLARGE_INTEGER);
  NTSTATUS NTAPI NtCreateSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				  PLARGE_INTEGER, ULONG, ULONG, HANDLE);
  NTSTATUS NTAPI NtCreateSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				    LONG, LONG);
  NTSTATUS NTAPI NtCreateSymbolicLinkObject (PHANDLE, ACCESS_MASK,
					     POBJECT_ATTRIBUTES,
					     PUNICODE_STRING);
  NTSTATUS NTAPI NtCreateTimer (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				TIMER_TYPE);
  NTSTATUS NTAPI NtCreateToken (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				TOKEN_TYPE, PLUID, PLARGE_INTEGER, PTOKEN_USER,
				PTOKEN_GROUPS, PTOKEN_PRIVILEGES, PTOKEN_OWNER,
				PTOKEN_PRIMARY_GROUP, PTOKEN_DEFAULT_DACL,
				PTOKEN_SOURCE);
  NTSTATUS NTAPI NtCreateTransaction (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				      LPGUID, HANDLE, ULONG, ULONG, ULONG,
				      PLARGE_INTEGER, PUNICODE_STRING);
  NTSTATUS NTAPI NtDuplicateToken (HANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
				   BOOLEAN, TOKEN_TYPE, PHANDLE);
  NTSTATUS NTAPI NtFsControlFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
				  PIO_STATUS_BLOCK, ULONG, PVOID, ULONG,
				  PVOID, ULONG);
  NTSTATUS NTAPI NtFlushBuffersFile (HANDLE, PIO_STATUS_BLOCK);
  NTSTATUS NTAPI NtLoadKey (POBJECT_ATTRIBUTES, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtLockFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			     PIO_STATUS_BLOCK, PLARGE_INTEGER, PLARGE_INTEGER,
			     ULONG, BOOLEAN, BOOLEAN);
  NTSTATUS NTAPI NtLockVirtualMemory (HANDLE, PVOID *, PSIZE_T, ULONG);
  NTSTATUS NTAPI NtMapViewOfSection (HANDLE, HANDLE, PVOID *, ULONG_PTR, SIZE_T,
				     PLARGE_INTEGER, PSIZE_T, SECTION_INHERIT,
				     ULONG, ULONG);
  NTSTATUS NTAPI NtMapViewOfSectionEx (HANDLE, HANDLE, PVOID *, PLARGE_INTEGER,
				       PSIZE_T, ULONG, ULONG,
				       PMEM_EXTENDED_PARAMETER, ULONG);
  NTSTATUS NTAPI NtNotifyChangeDirectoryFile (HANDLE, HANDLE, PIO_APC_ROUTINE,
					      PVOID, PIO_STATUS_BLOCK,
					      PFILE_NOTIFY_INFORMATION, ULONG,
					      ULONG, BOOLEAN);
  NTSTATUS NTAPI NtOpenDirectoryObject (PHANDLE, ACCESS_MASK,
					POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenEvent (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenFile (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES,
			     PIO_STATUS_BLOCK, ULONG, ULONG);
  NTSTATUS NTAPI NtOpenKey (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenMutant (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenProcessToken (HANDLE, ACCESS_MASK, PHANDLE);
  NTSTATUS NTAPI NtOpenThreadToken (HANDLE, ACCESS_MASK, BOOLEAN, PHANDLE);
  NTSTATUS NTAPI NtOpenSection (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenSemaphore (PHANDLE, ACCESS_MASK, POBJECT_ATTRIBUTES);
  NTSTATUS NTAPI NtOpenSymbolicLinkObject (PHANDLE, ACCESS_MASK,
					   POBJECT_ATTRIBUTES);
  /* WARNING!  Don't rely on the timestamp information returned by
     NtQueryAttributesFile.  Only the DOS file attribute info is reliable. */
  NTSTATUS NTAPI NtPrivilegeCheck (HANDLE, PPRIVILEGE_SET, PBOOLEAN);
  NTSTATUS NTAPI NtQueryAttributesFile (POBJECT_ATTRIBUTES,
					PFILE_BASIC_INFORMATION);
  NTSTATUS NTAPI NtQueryDirectoryFile(HANDLE, HANDLE, PVOID, PVOID,
				      PIO_STATUS_BLOCK, PVOID, ULONG,
				      FILE_INFORMATION_CLASS, BOOLEAN,
				      PUNICODE_STRING, BOOLEAN);
  NTSTATUS NTAPI NtQueryDirectoryObject (HANDLE, PVOID, ULONG, BOOLEAN,
					 BOOLEAN, PULONG, PULONG);
  NTSTATUS NTAPI NtQueryEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
				BOOLEAN, PVOID, ULONG, PULONG, BOOLEAN);
  NTSTATUS NTAPI NtQueryEvent (HANDLE, EVENT_INFORMATION_CLASS, PVOID, ULONG,
			       PULONG);
  NTSTATUS NTAPI NtQueryFullAttributesFile (POBJECT_ATTRIBUTES,
					    PFILE_NETWORK_OPEN_INFORMATION);
  NTSTATUS NTAPI NtQueryInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					 ULONG, FILE_INFORMATION_CLASS);
  NTSTATUS NTAPI NtQueryInformationProcess (HANDLE, PROCESSINFOCLASS,
					    PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQueryInformationThread (HANDLE, THREADINFOCLASS, PVOID,
					   ULONG, PULONG);
  NTSTATUS NTAPI NtQueryInformationToken (HANDLE, TOKEN_INFORMATION_CLASS,
					  PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQueryObject (HANDLE, OBJECT_INFORMATION_CLASS, PVOID, ULONG,
				PULONG);
  NTSTATUS NTAPI NtQueryQuotaInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					      ULONG, BOOLEAN, PVOID, ULONG,
					      PSID, BOOLEAN);
  NTSTATUS NTAPI NtQuerySemaphore (HANDLE, SEMAPHORE_INFORMATION_CLASS,
				   PVOID, ULONG, PULONG);
  NTSTATUS NTAPI NtQuerySystemInformation (SYSTEM_INFORMATION_CLASS,
					   PVOID, ULONG, PULONG);
  NTSTATUS WINAPI NtQuerySystemTime (PLARGE_INTEGER);
  NTSTATUS NTAPI NtQuerySecurityObject (HANDLE, SECURITY_INFORMATION,
					PSECURITY_DESCRIPTOR, ULONG, PULONG);
  NTSTATUS NTAPI NtQuerySymbolicLinkObject (HANDLE, PUNICODE_STRING, PULONG);
  NTSTATUS NTAPI NtQueryTimer (HANDLE, TIMER_INFORMATION_CLASS, PVOID,
			       ULONG, PULONG);
  NTSTATUS NTAPI NtQueryTimerResolution (PULONG, PULONG, PULONG);
  NTSTATUS NTAPI NtQueryValueKey (HANDLE, PUNICODE_STRING,
				  KEY_VALUE_INFORMATION_CLASS, PVOID, ULONG,
				  PULONG);
  NTSTATUS NTAPI NtQueryVirtualMemory (HANDLE, PVOID, MEMORY_INFORMATION_CLASS,
				       PVOID, SIZE_T, PSIZE_T);
  NTSTATUS NTAPI NtQueryVolumeInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					       ULONG, FS_INFORMATION_CLASS);
  NTSTATUS NTAPI NtReadFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			     PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
			     PULONG);
  NTSTATUS NTAPI NtRollbackTransaction (HANDLE, BOOLEAN);
  NTSTATUS NTAPI NtSetEaFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG);
  NTSTATUS NTAPI NtSetEvent (HANDLE, PULONG);
  NTSTATUS NTAPI NtSetInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID, ULONG,
				       FILE_INFORMATION_CLASS);
  NTSTATUS NTAPI NtSetInformationThread (HANDLE, THREADINFOCLASS, PVOID, ULONG);
  NTSTATUS NTAPI NtSetInformationToken (HANDLE, TOKEN_INFORMATION_CLASS, PVOID,
					ULONG);
  NTSTATUS NTAPI NtSetQuotaInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					    ULONG);
  NTSTATUS NTAPI NtSetSecurityObject (HANDLE, SECURITY_INFORMATION,
				      PSECURITY_DESCRIPTOR);
  NTSTATUS NTAPI NtSetTimer (HANDLE, PLARGE_INTEGER, PTIMER_APC_ROUTINE, PVOID,
			     BOOLEAN, LONG, PBOOLEAN);
  NTSTATUS NTAPI NtSetTimerResolution (ULONG, BOOLEAN, PULONG);
  NTSTATUS NTAPI NtSetValueKey (HANDLE, PUNICODE_STRING, ULONG, ULONG, PVOID,
				ULONG);
  NTSTATUS NTAPI NtSetVolumeInformationFile (HANDLE, PIO_STATUS_BLOCK, PVOID,
					     ULONG, FS_INFORMATION_CLASS);
  NTSTATUS NTAPI NtUnlockFile (HANDLE, PIO_STATUS_BLOCK, PLARGE_INTEGER,
			       PLARGE_INTEGER, ULONG);
  NTSTATUS NTAPI NtUnlockVirtualMemory (HANDLE, PVOID *, PSIZE_T, ULONG);
  NTSTATUS NTAPI NtUnmapViewOfSection (HANDLE, PVOID);
  NTSTATUS NTAPI NtWaitForSingleObject (HANDLE, BOOLEAN, PLARGE_INTEGER);
  NTSTATUS NTAPI NtWriteFile (HANDLE, HANDLE, PIO_APC_ROUTINE, PVOID,
			      PIO_STATUS_BLOCK, PVOID, ULONG, PLARGE_INTEGER,
			      PULONG);
  NTSTATUS NTAPI RtlAbsoluteToSelfRelativeSD (PSECURITY_DESCRIPTOR,
					      PSECURITY_DESCRIPTOR, PULONG);
  VOID NTAPI RtlAcquirePebLock ();
  NTSTATUS NTAPI RtlAddAccessAllowedAce (PACL, ULONG, ACCESS_MASK, PSID);
  NTSTATUS NTAPI RtlAddAccessAllowedAceEx (PACL, ULONG, ULONG, ACCESS_MASK,
					   PSID);
  NTSTATUS NTAPI RtlAddAccessDeniedAce (PACL, ULONG, ACCESS_MASK, PSID);
  NTSTATUS NTAPI RtlAddAccessDeniedAceEx (PACL, ULONG, ULONG, ACCESS_MASK,
					  PSID);
  NTSTATUS NTAPI RtlAddAce (PACL, ULONG, ULONG, PVOID, ULONG);
  PVOID NTAPI RtlAllocateHeap (PVOID, ULONG, SIZE_T);
  NTSTATUS NTAPI RtlAppendUnicodeToString (PUNICODE_STRING, PCWSTR);
  NTSTATUS NTAPI RtlAppendUnicodeStringToString (PUNICODE_STRING,
						 PUNICODE_STRING);
  NTSTATUS NTAPI RtlAnsiStringToUnicodeString (PUNICODE_STRING, PANSI_STRING,
					       BOOLEAN);
  NTSTATUS NTAPI RtlCheckRegistryKey (ULONG, PCWSTR);
  LONG NTAPI RtlCompareUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
				      BOOLEAN);
  NTSTATUS NTAPI RtlConvertSidToUnicodeString (PUNICODE_STRING, PSID, BOOLEAN);
  NTSTATUS NTAPI RtlConvertToAutoInheritSecurityObject (PSECURITY_DESCRIPTOR,
							PSECURITY_DESCRIPTOR,
							PSECURITY_DESCRIPTOR *,
							GUID *, BOOLEAN,
							PGENERIC_MAPPING);
  NTSTATUS NTAPI RtlCopySid (ULONG, PSID, PSID);
  VOID NTAPI RtlCopyUnicodeString (PUNICODE_STRING, PUNICODE_STRING);
  NTSTATUS NTAPI RtlCreateAcl (PACL, ULONG, ULONG);
  PDEBUG_BUFFER NTAPI RtlCreateQueryDebugBuffer (ULONG, BOOLEAN);
  NTSTATUS NTAPI RtlCreateRegistryKey (ULONG, PCWSTR);
  NTSTATUS NTAPI RtlCreateSecurityDescriptor (PSECURITY_DESCRIPTOR, ULONG);
  BOOLEAN NTAPI RtlCreateUnicodeStringFromAsciiz (PUNICODE_STRING, PCSTR);
  NTSTATUS NTAPI RtlDeleteSecurityObject (PSECURITY_DESCRIPTOR *);
  NTSTATUS NTAPI RtlDestroyQueryDebugBuffer (PDEBUG_BUFFER);
  NTSTATUS NTAPI RtlDowncaseUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					   BOOLEAN);
  NTSTATUS NTAPI RtlEnterCriticalSection (PRTL_CRITICAL_SECTION);
  BOOLEAN NTAPI RtlEqualPrefixSid (PSID, PSID);
  BOOLEAN NTAPI RtlEqualSid (PSID, PSID);
  BOOLEAN NTAPI RtlEqualUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
				       BOOLEAN);
  VOID NTAPI RtlFreeAnsiString (PANSI_STRING);
  BOOLEAN NTAPI RtlFreeHeap (HANDLE, ULONG, PVOID);
  VOID NTAPI RtlFreeOemString (POEM_STRING);
  VOID NTAPI RtlFreeUnicodeString (PUNICODE_STRING);
  BOOLEAN NTAPI RtlFirstFreeAce (PACL, PVOID *);
  NTSTATUS NTAPI RtlGetAce (PACL, ULONG, PVOID);
  NTSTATUS NTAPI RtlGetControlSecurityDescriptor (PSECURITY_DESCRIPTOR,
						  PSECURITY_DESCRIPTOR_CONTROL,
						  PULONG);
  HANDLE NTAPI RtlGetCurrentTransaction ();
  NTSTATUS NTAPI RtlGetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR, PBOOLEAN,
					       PACL *, PBOOLEAN);
  NTSTATUS NTAPI RtlGetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID *,
						PBOOLEAN);
  NTSTATUS NTAPI RtlGetNtVersionNumbers (LPDWORD, LPDWORD, LPDWORD);
  NTSTATUS NTAPI RtlGetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID *,
						PBOOLEAN);
  NTSTATUS NTAPI RtlGetVersion (PRTL_OSVERSIONINFOEXW);
  PSID_IDENTIFIER_AUTHORITY NTAPI RtlIdentifierAuthoritySid (PSID);
  VOID NTAPI RtlInitAnsiString (PANSI_STRING, PCSTR);
  NTSTATUS NTAPI RtlInitializeSid (PSID, PSID_IDENTIFIER_AUTHORITY, UCHAR);
  VOID NTAPI RtlInitUnicodeString (PUNICODE_STRING, PCWSTR);
  NTSTATUS NTAPI RtlIntegerToUnicodeString (ULONG, ULONG, PUNICODE_STRING);
  ULONG NTAPI RtlIsDosDeviceName_U (PCWSTR);
  NTSTATUS NTAPI RtlLeaveCriticalSection (PRTL_CRITICAL_SECTION);
  ULONG NTAPI RtlLengthSecurityDescriptor (PSECURITY_DESCRIPTOR);
  ULONG NTAPI RtlLengthSid (PSID);
  ULONG NTAPI RtlNtStatusToDosError (NTSTATUS);
  NTSTATUS NTAPI RtlOemStringToUnicodeString (PUNICODE_STRING, POEM_STRING,
					       BOOLEAN);
  BOOLEAN NTAPI RtlPrefixUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					BOOLEAN);
  NTSTATUS NTAPI RtlQueryProcessDebugInformation (ULONG, ULONG, PDEBUG_BUFFER);
  NTSTATUS NTAPI RtlQueryRegistryValues (ULONG, PCWSTR,
					 PRTL_QUERY_REGISTRY_TABLE, PVOID,
					 PVOID);
  VOID NTAPI RtlReleasePebLock ();
  VOID NTAPI RtlSecondsSince1970ToTime (ULONG, PLARGE_INTEGER);
  NTSTATUS NTAPI RtlSetCurrentDirectory_U (PUNICODE_STRING);
  BOOLEAN NTAPI RtlSetCurrentTransaction (HANDLE);
  NTSTATUS NTAPI RtlSetControlSecurityDescriptor (PSECURITY_DESCRIPTOR,
						  SECURITY_DESCRIPTOR_CONTROL,
						  SECURITY_DESCRIPTOR_CONTROL);
  NTSTATUS NTAPI RtlSetDaclSecurityDescriptor (PSECURITY_DESCRIPTOR, BOOLEAN,
					       PACL, BOOLEAN);
  NTSTATUS NTAPI RtlSetGroupSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID,
						BOOLEAN);
  NTSTATUS NTAPI RtlSetOwnerSecurityDescriptor (PSECURITY_DESCRIPTOR, PSID,
						BOOLEAN);
  PUCHAR NTAPI RtlSubAuthorityCountSid (PSID);
  PULONG NTAPI RtlSubAuthoritySid (PSID, ULONG);
  ULONG NTAPI RtlUnicodeStringToAnsiSize (PUNICODE_STRING);
  NTSTATUS NTAPI RtlUnicodeStringToAnsiString (PANSI_STRING, PUNICODE_STRING,
					       BOOLEAN);
  NTSTATUS NTAPI RtlUnicodeStringToOemString (PANSI_STRING, PUNICODE_STRING,
					      BOOLEAN);
  WCHAR NTAPI RtlUpcaseUnicodeChar (WCHAR);
  NTSTATUS NTAPI RtlUpcaseUnicodeString (PUNICODE_STRING, PUNICODE_STRING,
					 BOOLEAN);
  NTSTATUS NTAPI RtlWriteRegistryValue (ULONG, PCWSTR, PCWSTR, ULONG, PVOID,
					ULONG);

#ifdef __cplusplus
  /* A few Rtl functions are either actually macros, or they just don't
     exist even though they would be a big help.  We implement them here,
     partly as inline functions. */

  /* RtlInitEmptyUnicodeString is defined as a macro in wdm.h, but that file
     is missing entirely in w32api. */
  inline
  VOID NTAPI RtlInitEmptyUnicodeString(PUNICODE_STRING dest, PCWSTR buf,
				       USHORT len)
  {
    dest->Length = 0;
    dest->MaximumLength = len;
    dest->Buffer = (PWSTR) buf;
  }
  /* Like RtlInitEmptyUnicodeString, but initialize Length to len, too.
     This is for instance useful when creating a UNICODE_STRING from an
     NtQueryInformationFile info buffer, where the length of the filename
     is known, but you can't rely on the string being 0-terminated.
     If you know it's 0-terminated, just use RtlInitUnicodeString(). */
  inline
  VOID NTAPI RtlInitCountedUnicodeString (PUNICODE_STRING dest, PCWSTR buf,
					  USHORT len)
  {
    dest->Length = dest->MaximumLength = len;
    dest->Buffer = (PWSTR) buf;
  }
  /* Split path into dirname and basename part.  This function does not
     copy anything!  It just initializes the dirname and basename
     UNICODE_STRINGs so that their Buffer members point to the right spot
     into path's Buffer, and the Length (and MaximumLength) members are set
     to match the dirname part and the basename part.
     Note that dirname's Length is set so that it also includes the trailing
     backslash.  If you don't need it, just subtract sizeof(WCHAR) from
     dirname.Length. */
  inline
  VOID NTAPI RtlSplitUnicodePath (PUNICODE_STRING path, PUNICODE_STRING dirname,
				  PUNICODE_STRING basename)
  {
    USHORT len = path->Length / sizeof (WCHAR);
    while (len > 0 && path->Buffer[--len] != L'\\')
      ;
    ++len;
    if (dirname)
      RtlInitCountedUnicodeString (dirname, path->Buffer, len * sizeof (WCHAR));
    if (basename)
      RtlInitCountedUnicodeString (basename, &path->Buffer[len],
				   path->Length - len * sizeof (WCHAR));
  }
  /* Check if prefix is a prefix of path. */
  inline
  BOOLEAN NTAPI RtlEqualUnicodePathPrefix (PUNICODE_STRING path,
					   PUNICODE_STRING prefix,
					   BOOLEAN caseinsensitive)
  {
    UNICODE_STRING p;

    RtlInitCountedUnicodeString (&p, path->Buffer,
				 prefix->Length < path->Length
				 ? prefix->Length : path->Length);
    return RtlEqualUnicodeString (&p, prefix, caseinsensitive);
  }
  /* Check if suffix is a suffix of path. */
  inline
  BOOL NTAPI RtlEqualUnicodePathSuffix (PUNICODE_STRING path,
					PUNICODE_STRING suffix,
					BOOLEAN caseinsensitive)
  {
    UNICODE_STRING p;

    if (suffix->Length < path->Length)
      RtlInitCountedUnicodeString (&p, (PWCHAR) ((PBYTE) path->Buffer
				       + path->Length - suffix->Length),
				   suffix->Length);
    else
      RtlInitCountedUnicodeString (&p, path->Buffer, path->Length);
    return RtlEqualUnicodeString (&p, suffix, caseinsensitive);
  }
  /* Implemented in strfuncs.cc.  Create a Hex UNICODE_STRING from a given
     64 bit integer value.  If append is TRUE, append the hex string,
     otherwise overwrite dest.  Returns either STATUS_SUCCESS, or
     STATUS_BUFFER_OVERFLOW, if the unicode buffer is too small (hasn't
     room for 16 WCHARs). */
  NTSTATUS NTAPI RtlInt64ToHexUnicodeString (ULONGLONG value,
					     PUNICODE_STRING dest,
					     BOOLEAN append);
  /* Set file attributes.  Don't change file times. */
  inline
  NTSTATUS NTAPI NtSetAttributesFile (HANDLE h, ULONG attr)
  {
    IO_STATUS_BLOCK io;
    FILE_BASIC_INFORMATION fbi;
    fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart =
    fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL;
    fbi.FileAttributes = attr ?: FILE_ATTRIBUTE_NORMAL;
    return NtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
  }

  /* This test for a signalled event is twice as fast as calling
     WaitForSingleObject (event, 0). */
  inline
  BOOL NTAPI IsEventSignalled (HANDLE event)
  {
    EVENT_BASIC_INFORMATION ebi;
    return NT_SUCCESS (NtQueryEvent (event, EventBasicInformation,
				     &ebi, sizeof ebi, NULL))
	   && ebi.SignalState != 0;

  }

  static inline void
  start_transaction (HANDLE &old_trans, HANDLE &trans)
  {
    NTSTATUS status = NtCreateTransaction (&trans,
				  SYNCHRONIZE | TRANSACTION_ALL_ACCESS,
				  NULL, NULL, NULL, 0, 0, 0, NULL, NULL);
    if (NT_SUCCESS (status))
      {
	old_trans = RtlGetCurrentTransaction ();
	RtlSetCurrentTransaction (trans);
      }
    else
      old_trans = trans = NULL;
  }

  static inline NTSTATUS
  stop_transaction (NTSTATUS status, HANDLE old_trans, HANDLE &trans)
  {
    RtlSetCurrentTransaction (old_trans);
    if (NT_SUCCESS (status))
      status = NtCommitTransaction (trans, TRUE);
    else
      status = NtRollbackTransaction (trans, TRUE);
    NtClose (trans);
    trans = NULL;
    return status;
  }
}

/* This is for pseudo console workaround. ClosePseudoConsole()
   seems to have a bug that one internal handle remains opend.
   This causes handle leak. To close this handle, it is needed
   to access internal of HPCON. HPCON_INTERNAL is defined for
   this purpose. The structure of internal of HPCON is not
   documented. Refer to: https://github.com/Biswa96/XConPty */
typedef struct _HPCON_INTERNAL
{
  HANDLE hWritePipe;
  HANDLE hConDrvReference;
  HANDLE hConHostProcess;
} HPCON_INTERNAL;
#endif
